﻿// ---------------------------------------------------------------------------------------
//                                        ILGPU
//                        Copyright (c) 2018-2023 ILGPU Project
//                                    www.ilgpu.net
//
// File: Driver.cs
//
// This file is part of ILGPU and is distributed under the University of Illinois Open
// Source License. See LICENSE.txt for details.
// ---------------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.42000
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

using ILGPU.IR.Values;
using System;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;

namespace ILGPU.Frontend
{
    partial class CodeGenerator
    {
        [SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode")]
        [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
        private bool TryGenerateCode(ILInstruction instruction)
        {
            switch (instruction.InstructionType)
            {
                case ILInstructionType.Nop:
                    MakeNop();
                    return true;
                case ILInstructionType.Break:
                    MakeTrap();
                    return true;
                case ILInstructionType.LdToken:
                    MakeLoadToken(instruction.Argument);
                    return true;

                case ILInstructionType.Ldarg:
                    {
                        var index = instruction.GetArgumentAs<int>() -
                            LambdaArgumentOffset;
                        if (index >= 0)
                        {
                            LoadVariable(
                                new VariableRef(
                                    index,
                                    VariableRefType.Argument));
                        }
                    }
                    return true;
                case ILInstructionType.Ldarga:
                    {
                        var index = instruction.GetArgumentAs<int>() -
                            LambdaArgumentOffset;
                        if (index >= 0)
                        {
                            LoadVariableAddress(
                                new VariableRef(
                                    index,
                                    VariableRefType.Argument));
                        }
                    }
                    return true;
                case ILInstructionType.Starg:
                    {
                        var index = instruction.GetArgumentAs<int>() -
                            LambdaArgumentOffset;
                        if (index >= 0)
                        {
                            StoreVariable(
                                new VariableRef(
                                    index,
                                    VariableRefType.Argument));
                        }
                    }
                    return true;

                case ILInstructionType.Ldloc:
                    LoadVariable(
                        new VariableRef(
                            instruction.GetArgumentAs<int>(),
                            VariableRefType.Local));
                    return true;
                case ILInstructionType.Ldloca:
                    LoadVariableAddress(
                        new VariableRef(
                            instruction.GetArgumentAs<int>(),
                            VariableRefType.Local));
                    return true;
                case ILInstructionType.Stloc:
                    StoreVariable(
                        new VariableRef(
                            instruction.GetArgumentAs<int>(),
                            VariableRefType.Local));
                    return true;

                case ILInstructionType.LdI4:
                    Load(instruction.GetArgumentAs<int>());
                    return true;
                case ILInstructionType.LdI8:
                    Load(instruction.GetArgumentAs<long>());
                    return true;
                case ILInstructionType.LdR4:
                    Load(instruction.GetArgumentAs<float>());
                    return true;
                case ILInstructionType.LdR8:
                    Load(instruction.GetArgumentAs<double>());
                    return true;
                case ILInstructionType.Ldstr:
                    LoadString(instruction.GetArgumentAs<string>());
                    return true;

                case ILInstructionType.Dup:
                    MakeDup();
                    return true;
                case ILInstructionType.Pop:
                    MakePop();
                    return true;
                case ILInstructionType.Ret:
                    MakeReturn();
                    return true;
                case ILInstructionType.Call:
                    MakeCall(instruction);
                    return true;
                case ILInstructionType.Callvirt:
                    MakeVirtualCall(instruction);
                    return true;
                case ILInstructionType.Calli:
                    MakeCalli(instruction.Argument);
                    return true;
                case ILInstructionType.Jmp:
                    MakeJump(instruction.GetArgumentAs<MethodBase>());
                    return true;

                case ILInstructionType.Box:
                    MakeBox();
                    return true;
                case ILInstructionType.Unbox:
                    MakeUnbox(instruction.GetArgumentAs<Type>());
                    return true;

                case ILInstructionType.Br:
                    MakeBranch();
                    return true;

                case ILInstructionType.Brfalse:
                    MakeBranchFalse();
                    return true;
                case ILInstructionType.Brtrue:
                    MakeBranchTrue();
                    return true;

                case ILInstructionType.Beq:
                    MakeBranch(CompareKind.Equal, instruction.Flags);
                    return true;
                case ILInstructionType.Bne:
                    MakeBranch(CompareKind.NotEqual, instruction.Flags);
                    return true;
                case ILInstructionType.Bge:
                    MakeBranch(CompareKind.GreaterEqual, instruction.Flags);
                    return true;
                case ILInstructionType.Bgt:
                    MakeBranch(CompareKind.GreaterThan, instruction.Flags);
                    return true;
                case ILInstructionType.Ble:
                    MakeBranch(CompareKind.LessEqual, instruction.Flags);
                    return true;
                case ILInstructionType.Blt:
                    MakeBranch(CompareKind.LessThan, instruction.Flags);
                    return true;

                case ILInstructionType.Switch:
                    MakeSwitch(instruction.GetArgumentAs<ILInstructionBranchTargets>());
                    return true;

                case ILInstructionType.Add:
                    MakeArithmetic(BinaryArithmeticKind.Add, instruction);
                    return true;
                case ILInstructionType.Sub:
                    MakeArithmetic(BinaryArithmeticKind.Sub, instruction);
                    return true;
                case ILInstructionType.Mul:
                    MakeArithmetic(BinaryArithmeticKind.Mul, instruction);
                    return true;
                case ILInstructionType.Div:
                    MakeArithmetic(BinaryArithmeticKind.Div, instruction);
                    return true;
                case ILInstructionType.Rem:
                    MakeArithmetic(BinaryArithmeticKind.Rem, instruction);
                    return true;
                case ILInstructionType.And:
                    MakeArithmetic(BinaryArithmeticKind.And, instruction);
                    return true;
                case ILInstructionType.Or:
                    MakeArithmetic(BinaryArithmeticKind.Or, instruction);
                    return true;
                case ILInstructionType.Xor:
                    MakeArithmetic(BinaryArithmeticKind.Xor, instruction);
                    return true;
                case ILInstructionType.Shl:
                    MakeArithmetic(BinaryArithmeticKind.Shl, instruction);
                    return true;
                case ILInstructionType.Shr:
                    MakeArithmetic(BinaryArithmeticKind.Shr, instruction);
                    return true;
                case ILInstructionType.Neg:
                    MakeArithmetic(UnaryArithmeticKind.Neg);
                    return true;
                case ILInstructionType.Not:
                    MakeArithmetic(UnaryArithmeticKind.Not);
                    return true;

                case ILInstructionType.Conv:
                    MakeConvert(instruction.GetArgumentAs<Type>(), instruction.Flags);
                    return true;

                case ILInstructionType.Initobj:
                    MakeInitObject(instruction.GetArgumentAs<Type>());
                    return true;
                case ILInstructionType.Newobj:
                    MakeNewObject(instruction.GetArgumentAs<MethodBase>());
                    return true;
                case ILInstructionType.Isinst:
                    MakeIsInstance(instruction.GetArgumentAs<Type>());
                    return true;

                case ILInstructionType.Ldfld:
                    MakeLoadField(instruction.GetArgumentAs<FieldInfo>());
                    return true;
                case ILInstructionType.Ldsfld:
                    MakeLoadStaticField(instruction.GetArgumentAs<FieldInfo>());
                    return true;
                case ILInstructionType.Ldflda:
                    MakeLoadFieldAddress(instruction.GetArgumentAs<FieldInfo>());
                    return true;
                case ILInstructionType.Ldsflda:
                    MakeLoadStaticFieldAddress(instruction.GetArgumentAs<FieldInfo>());
                    return true;
                case ILInstructionType.Stfld:
                    MakeStoreField(instruction.GetArgumentAs<FieldInfo>());
                    return true;
                case ILInstructionType.Stsfld:
                    MakeStoreStaticField(instruction.GetArgumentAs<FieldInfo>());
                    return true;

                case ILInstructionType.Ceq:
                    MakeCompare(CompareKind.Equal, instruction.Flags);
                    return true;
                case ILInstructionType.Cgt:
                    MakeCompare(CompareKind.GreaterThan, instruction.Flags);
                    return true;
                case ILInstructionType.Clt:
                    MakeCompare(CompareKind.LessThan, instruction.Flags);
                    return true;

                case ILInstructionType.Ldobj:
                case ILInstructionType.Ldind:
                    MakeLoadObject(instruction.GetArgumentAs<Type>());
                    return true;
                case ILInstructionType.Stobj:
                case ILInstructionType.Stind:
                    MakeStoreObject(instruction.GetArgumentAs<Type>());
                    return true;

                case ILInstructionType.Newarr:
                    MakeNewArray(instruction.GetArgumentAs<Type>());
                    return true;
                case ILInstructionType.Ldelem:
                    MakeLoadElement(instruction.GetArgumentAs<Type>());
                    return true;
                case ILInstructionType.Ldelema:
                    MakeLoadElementAddress(instruction.GetArgumentAs<Type>());
                    return true;
                case ILInstructionType.Stelem:
                    MakeStoreElement(instruction.GetArgumentAs<Type>());
                    return true;
                case ILInstructionType.Ldlen:
                    MakeLoadArrayLength();
                    return true;

                case ILInstructionType.SizeOf:
                    LoadSizeOf(instruction.GetArgumentAs<Type>());
                    return true;

                default:
                    return false;
            }
        }
    }
}
